/*
 * Singularity Engine
 * Copyright (C) 2010 Vyacheslav Vorobyov, All rights reserved.
 * See LICENSE for full license information.
 */

/**
 * 
 */
package org.singularity.mapred;

import org.singularity.io.Input;
import org.singularity.io.Output;


/**
 * <p>
 * This concept incorporates the notion of a MapReduce cascade. 
 * This interface specifies a functions necessary to build complex 
 * data processing flows in a similar with MapReduce paradigm. 
 * </p>
 * <p>
 * Note that MapReduce here is slightly differs from well known 
 * in industry such as Hadoop(Google) like, or GridGain like. 
 * Actually it is a child of two parents - MapReduce and Rete 
 * (production system) algorithms. So, this is a <strong>continuos, 
 * incremental, cascaded, massively parallel, distributed(in future), 
 * production system</strong> inspired by MapReduce & Rete algorithms.
 * </p>
 * <p>
 * Technically, cascade can be viewed as a directed, acyclic graph (DAG)
 * of a specific vertices (elements) and edges(flows).
 * </p>  
 * 
 * @author vjache
 * 
 * @see ReduceElement
 * @see InputElement
 * @see OutputElement
 * @see RedFun
 * @see MapFun
 */
public interface Cascade {
	/**
	 * Creates and adds reduce element to the cascade based 
	 * on reduce function specified.
	 * @param <KT> - a key type of a VDME.
	 * @param <RT> - a result type after reduction.
	 * @param - aRedFun - a reduce function.
	 * @return a reduce element, a vertex of cascade graph.
	 * 
	 * @see RedFun
	 * @see VDME
	 */
	<KT, RT> ReduceElement<KT,RT> 	createReducer(RedFun<KT, RT> aRedFun);
	/**
	 * Creates and adds input element to the cascade based on input 
	 * factory specified.
	 * @param <VT> - a values type that are obtained from input.
	 * @param aInput - a factory that "knows where to get input data stream from". 
	 * @return an input element, a vertex of cascade graph.
	 * 
	 * @see Input
	 * @see InputElement
	 */
	<VT> InputElement<VT> 			createInput(Input<VT> aInput);
	/**
	 * Creates and adds output element to the cascade based on output 
	 * factory specified.
	 * @param <VT> - a values type that are pushed to output.
	 * @param aOutput - a factory that provides a pipe to push data to.
	 * @return an output element, a vertex of cascade graph.
	 */
	<VT> OutputElement<VT> 			createOutput(Output<VT> aOutput);
	/**
	 * Creates and connects two elements of the cascade that are 
	 * already created - any source able element and terminal element 
	 * i.e. output element. 
	 * @param <VT> - a values type to be pushed to output.
	 * @param aFrom - any source able element like input or reduce ones.
	 * @param aTo - an output element.
	 */
	<VT> void 		flow(Source aFrom, OutputElement<VT> aTo);
	/**
	 * Creates and connects two elements of the cascade that are 
	 * already created - any source able element and reduce element. 
	 * This data flow is parametrized with a map function, so the data 
	 * flow is processed in such a way that input stream of values 
	 * transformed to a key-value stream: V->{K,V}.  
	 * @param <VT0> - a type of initial values.
	 * @param <KT> - a type of keys after value mapping process.
	 * @param <VT> - a type of values after value mapping process.
	 * @param aFrom - a source able element.
	 * @param aTo - a destination element that can eat key value pairs, 
	 * currently only one such an element is possible - reduce element.
	 * @param aMapFun - a map function that transforms a values to 
	 * corresponding key-value pairs.
	 */
	<VT0, KT, VT> void 	flow(Source aFrom, Destination aTo, MapFun<VT0,KT, VT> aMapFun);
}
